package spring_learn.a15;


import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

//模拟将advice类定义的通知转换成advisor
public class A15_2 {


    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        DefaultListableBeanFactory beanFactory=new DefaultListableBeanFactory();
        beanFactory.registerBeanDefinition("advice1",
                BeanDefinitionBuilder.genericBeanDefinition(Advice1.class).getBeanDefinition());
        beanFactory.registerBeanDefinition("advice2",
                BeanDefinitionBuilder.genericBeanDefinition(Advice2.class).getBeanDefinition());
        AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator=new AnnotationAwareAspectJAutoProxyCreator();
        annotationAwareAspectJAutoProxyCreator.setBeanFactory(beanFactory);
        Method findEligibleAdvisors = AbstractAdvisorAutoProxyCreator.class.getDeclaredMethod("findEligibleAdvisors", Class.class, String.class);
        findEligibleAdvisors.setAccessible(true);
        List res = (List)findEligibleAdvisors.invoke(annotationAwareAspectJAutoProxyCreator, Bean1.class, "bean1");
        System.out.println(">>>>>>>>>>>>>>>>>>");
        for (Object re : res) {
            System.out.println(re);
        }
    }


    static class Bean1{
        public void foo(){
            System.out.println("foo");
        }
    }

    @Aspect
    class Advice1{

        @Before("execution(* foo())")
        public void f1(){};
    }


    @Aspect
    class Advice2{

        @Before("execution(* foo())")
        public void f1(){};
    }

}
